#include "../http/HttpServer.h"
#include "../http/HttpData.h"
#include "../http/HttpDecoder.h"
#include "../common/global.h"
#include "../common/CCReactor.h"
#include <iostream>
#include <string>
#include <thread>
#include <chrono>
#include <cassert>

class HttpServerTest {
public:
    HttpServerTest() : server_started(false) {}
    
    bool TestBasicFunctionality() {
        std::cout << "Testing basic HTTP server functionality..." << std::endl;
        
        // Initialize reactor
        g_reactor->Init();
        g_reactor->Start();
        
        // Create server
        HttpServer server;
        
        // Set up test handler
        auto handler = [this, &server](uint32_t handle, stHttpRequest&& req) -> int {
            request_count++;
            last_request = std::move(req);
            
            // Create response
            stHttpResponse resp;
            resp.state = 200;
            resp.heads["Content-Type"] = "text/plain";
            resp.heads["Server"] = "HttpLib/1.0";
            
            if (req.url == "/") {
                resp.body = "Hello, World!";
            } else if (req.url == "/test") {
                resp.body = "Test page";
            } else if (req.url == "/json") {
                resp.heads["Content-Type"] = "application/json";
                resp.body = "{\"status\": \"ok\", \"count\": " + std::to_string(request_count) + "}";
            } else {
                resp.state = 404;
                resp.body = "Not Found";
            }
            
            // Send response
            server.Response(handle, std::move(resp));
            return 0;
        };
        
        // Start server
        int result = server.Start("127.0.0.1", 8081, handler);
        if (result != 0) {
            std::cerr << "Failed to start server" << std::endl;
            return false;
        }
        
        server_started = true;
        std::cout << "Server started on http://127.0.0.1:8081" << std::endl;
        
        // Wait a bit for server to be ready
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
        
        return true;
    }
    
    void TestRequestHandling() {
        std::cout << "Testing request handling..." << std::endl;
        
        // Note: In a real test, we would use an HTTP client to send requests
        // For now, we'll just test the internal logic
        
        // Test request parsing (this would be done by the decoder)
        stHttpRequest test_req;
        test_req.method = "GET";
        test_req.url = "/test";
        test_req.heads["User-Agent"] = "TestClient";
        test_req.heads["Accept"] = "text/html";
        test_req.body = "";
        
        // Verify request structure
        assert(test_req.method == "GET");
        assert(test_req.url == "/test");
        assert(test_req.heads.size() == 2);
        assert(test_req.body.empty());
        
        std::cout << "Request structure test passed" << std::endl;
    }
    
    void TestResponseHandling() {
        std::cout << "Testing response handling..." << std::endl;
        
        // Test response creation
        stHttpResponse test_resp;
        test_resp.state = 200;
        test_resp.heads["Content-Type"] = "text/plain";
        test_resp.heads["Server"] = "HttpLib/1.0";
        test_resp.body = "Hello, World!";
        
        // Verify response structure
        assert(test_resp.state == 200);
        assert(test_resp.heads.size() == 2);
        assert(test_resp.body == "Hello, World!");
        
        // Test response serialization
        std::string resp_str = test_resp.ToString();
        assert(!resp_str.empty());
        assert(resp_str.find("state:200") != std::string::npos);
        assert(resp_str.find("Hello, World!") != std::string::npos);
        
        std::cout << "Response structure test passed" << std::endl;
    }
    
    void TestUrlParsing() {
        std::cout << "Testing URL parsing..." << std::endl;
        
        // Test URL parsing
        stUrlData url_data;
        std::string test_url = "http://example.com:8080/path/to/resource?param1=value1&param2=value2#fragment";
        
        bool result = HttpDecoder::ParserUrl(url_data, test_url);
        assert(result);
        
        // Verify parsed components
        assert(url_data.schema == "http");
        assert(url_data.host == "example.com");
        assert(url_data.port == "8080");
        assert(url_data.path == "/path/to/resource");
        
        std::cout << "URL parsing test passed" << std::endl;
    }
    
    void Cleanup() {
        if (server_started) {
            std::cout << "Cleaning up server..." << std::endl;
            g_reactor->Stop();
            server_started = false;
        }
    }
    
private:
    bool server_started;
    int request_count = 0;
    stHttpRequest last_request;
    HttpServer server;
};

int main() {
    std::cout << "HTTP Server Test Suite" << std::endl;
    
    HttpServerTest test_suite;
    
    // Run tests
    bool all_tests_passed = true;
    
    try {
        if (!test_suite.TestBasicFunctionality()) {
            all_tests_passed = false;
        }
        
        test_suite.TestRequestHandling();
        test_suite.TestResponseHandling();
        test_suite.TestUrlParsing();
        
        std::cout << "\nAll tests completed!" << std::endl;
        
    } catch (const std::exception& e) {
        std::cerr << "Test failed with exception: " << e.what() << std::endl;
        all_tests_passed = false;
    }
    
    test_suite.Cleanup();
    
    return all_tests_passed ? 0 : 1;
}